package androidlab.sprintingsquirrel.game;

import static org.andengine.extension.physics.box2d.util.constants.PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT;

import org.andengine.engine.camera.BoundCamera;
import org.andengine.entity.sprite.AnimatedSprite;
import org.andengine.extension.physics.box2d.PhysicsConnector;
import org.andengine.extension.physics.box2d.PhysicsFactory;
import org.andengine.extension.physics.box2d.PhysicsWorld;
import org.andengine.opengl.vbo.VertexBufferObjectManager;

import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;
import com.badlogic.gdx.physics.box2d.Fixture;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.badlogic.gdx.physics.box2d.PolygonShape;

import androidlab.sprintingsquirrel.ResourceManager;

public abstract class Player extends AnimatedSprite {
	
	private Body body;
	private int contactCounter = 0;
	
	public Player(float pX, float pY, VertexBufferObjectManager vbo, BoundCamera camera, PhysicsWorld physicsWorld){
		super(pX, pY, ResourceManager.getInstance().playerTR, vbo);
		createPhysics(camera, physicsWorld);
		camera.setChaseEntity(this);
	}
	
	private void createPhysics(final BoundCamera camera, PhysicsWorld physicsWorld) {
	    body = PhysicsFactory.createBoxBody(physicsWorld, this, BodyType.DynamicBody, PhysicsFactory.createFixtureDef(0f, 0f, 0f));

	    body.setUserData("player");
	    body.setFixedRotation(true);
	    body.setBullet(true);
	    
	    final PolygonShape poly = new PolygonShape();
	    poly.setAsBox(22f/PIXEL_TO_METER_RATIO_DEFAULT, 2f/PIXEL_TO_METER_RATIO_DEFAULT, new Vector2(0f, 32f/PIXEL_TO_METER_RATIO_DEFAULT), 0);
	    
	    FixtureDef fixtureDef = PhysicsFactory.createFixtureDef(0f, 0f, 0f, true);
	    fixtureDef.shape = poly;
	    
	    Fixture feet = body.createFixture(fixtureDef);
	    feet.setUserData("feet");
	    poly.dispose();
	    
	    physicsWorld.registerPhysicsConnector(new PhysicsConnector(this, body, true, false) {
	        @Override
	        public void onUpdate(float pSecondsElapsed) {
	            super.onUpdate(pSecondsElapsed);
	            camera.onUpdate(0.1f);
	            
	            if (getY() > camera.getBoundsHeight()) {                    
	                onDie();
	            }
	        }
	    });
	}
	
	public void run(float xValue) {
		body.setLinearVelocity(new Vector2(xValue*12, body.getLinearVelocity().y));

		final long[] PLAYER_ANIMATE = new long[] { 30, 30, 30 };
		if(xValue > 0.00001) {
			if(contactCounter > 0) {
				animate(PLAYER_ANIMATE, 0, 2,  true);
			}
			else {
				stopAnimation();
				setCurrentTileIndex(3);
			}
		}
		else if(xValue < -0.00001) {
			if(contactCounter > 0) {
				animate(PLAYER_ANIMATE, 5, 7,  true);
			}
			else {
				stopAnimation();
				setCurrentTileIndex(4);
			}
		}
		else {
			stopAnimation();
		}
	}
	
	public void jump() {
		if(getCurrentTileIndex() == 0 || getCurrentTileIndex() == 1 || getCurrentTileIndex() == 2) {
			setCurrentTileIndex(3);
		}
		else if(getCurrentTileIndex() == 5 || getCurrentTileIndex() == 6 || getCurrentTileIndex() == 7) {
			setCurrentTileIndex(4);
		}
		ResourceManager.getInstance().jumpSound.play();
	    body.setLinearVelocity(new Vector2(body.getLinearVelocity().x, -30));
	}
	
	public void setContactCounter(int contactCount) {
		contactCounter = contactCount;
	}
	
	public abstract void onDie();
}
